-- 运营活动: 累计登录


--[[
{
    cmd_id = 1, -- 命令id，用于批量停止、删除活动 
    act_id = 75, -- 活动id (75 累计登录)
    act_name = "累计登录", -- 活动名称
    act_desc = "活动期间获取经验达到对应档次则可领取丰厚奖励！", -- 活动描述
    beg_time = 1493262000,  -- 活动开始时间(unix timestamp)
    end_time = 1593267400,  -- 活动结束时间(unix timestamp)
    config = -- 配置数据
    {
        Awards =
        {
            {
                desc = "累计登录1天",
                cond = 1,
                awards = 
                {
                    { type = 0, id = 509, count = 1, bind = 1, },
                    { type = 0, id = 559, count = 2, bind = 1, },
                },
            },
            {
                desc = "累计登录2天",
                cond = 2,
                awards = 
                {
                    { type = 0, id = 509, count = 1, bind = 1, },
                    { type = 0, id = 559, count = 2, bind = 1, },
                },
            },
            {
                desc = "累计登录3天",
                cond = 3,
                awards = 
                {
                    { type = 0, id = 509, count = 1, bind = 1, },
                    { type = 0, id = 559, count = 2, bind = 1, },
                },
            },
        },
    },
}
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_75_check_cfg(cfg)
    if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
    
    if config.Awards == nil then return 23 end
    if type(config.Awards) ~= "table" then return 24 end
    for idx = 1, #config.Awards do
        local dayRewards = config.Awards[idx]
        if dayRewards == nil then return 25 end
        if type(dayRewards) ~= "table" then return 26 end
        if dayRewards.awards == nil then return 27 end
        if type(dayRewards.awards) ~= "table" then return 28 end
        if not oper_act_check_one_award_cfg(dayRewards.awards) then
            return 22
        end 
    end

    return 0
end

-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_75_setup(cfg) 
    return 0
end

-- 卸载活动
function oper_act_75_unsetup(cfg)   
end

-- 活动开始
function oper_act_75_start(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_75_start = 1
    ssVar.oper_act_75_cmd = cfg.cmd_id
    ssVar.oper_act_75_act = cfg.act_id

    local data = gRankMgr_GetValueByIndx(0, RANK_DEFINE_OPERATION_75, 1)

    if data then
        local myData = BaseFuc_unserialize(data)
        if myData and myData.cmd_id and myData.cmd_id == cfg.cmd_id and myData.act_id and myData.act_id == cfg.act_id and
            myData.time and cfg.beg_time <= myData.time and  cfg.end_time > myData.time then
            return
        end
    end

    gRankMgr_Clear(RANK_DEFINE_OPERATION_75)
end

-- 活动结束
function oper_act_75_end(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_75_start = nil
    ssVar.oper_act_75_cmd = nil
    ssVar.oper_act_75_act = nil

    if not cfg then return end
    local config = cfg.config
    if not config then return end

end

-- 打包数据
function oper_act_75_packet_data(sysarg, cfg)
    --print("oper_act_75_packet_data pass here")
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_75_start then
        return
    end
    if not cfg then return end
    local config = cfg.config
    if not config then return end

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_75, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    local time = System.getSystemTime()

    if not myData.myGold then       --特殊处理，当没有登录天数的时候直接给他加一天
        --oper_act_75_crossday(sysarg)
        --return
        myData.myGold = 1
        if not myData.myGoldData then
            myData.myGoldData = {}
        end
        for idx = 1, #config.Awards do
            if myData.myGoldData[idx] and myData.myGoldData[idx] >= 1 then
            else
                if config.Awards[idx].cond <= myData.myGold then
                    myData.myGoldData[idx] = 1
                end
            end
        end


        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        myData.mySelfTime = time

        local newData = BaseFuc_serialize(myData)
        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_75, 1, newData)
    end
    if not myData.myGoldData then
        myData.myGoldData = {}
    end

    if not myData.myGoldBuyCount then
        myData.myGoldBuyCount = 0
    end

    local canBuy = 0
    if cfg.end_time - time <= config.canSignBuyGoldTime then
        canBuy = 1
    end

    local pack = oper_act_alloc_init_data_packet(sysarg, cfg.cmd_id, cfg.act_id)
    if (pack == nil) then
        return
    end
    DataPack.writeByte(pack, canBuy)
    DataPack.writeByte(pack, myData.myGoldBuyCount)
    --print("oper_act_75_packet_data myData.myGold ="..myData.myGold)
    DataPack.writeByte(pack, myData.myGold or 0)
    local len = #config.Awards
    DataPack.writeByte(pack, len)
    for idx = 1, len do
        local state = myData.myGoldData[idx] or 0
        --print("oper_act_75_packet_data state ="..state)
        DataPack.writeByte(pack, state)
    end
    DataPack.flush(pack)
    
    --DataPack.writeByte(netPack, 1)        -- 活动特有参数
end

-- 操作，返回操作结果，0为成功
function oper_act_75_do(sysarg, cfg, clientPkt)
    if cfg == nil then return end
    
    if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
        Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
        return
    end
    
    local config = cfg.config
    if config == nil then -- 参数错误
        print("error, oper_act_75_do cfg.config confg error")
        return
    end
    local opType = DataPack.readByte(clientPkt) 
    local Index = DataPack.readByte(clientPkt)
    
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_75_start then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation004, ttFlyTip)
        return
    end
   
    if Index > #config.Awards then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation005, ttFlyTip)
        return
    end

    local time = System.getSystemTime()

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_75, 1)
    local myData = BaseFuc_unserialize(data)

    if opType == 1 then
        if not myData then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end
        if not myData.myGoldData then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end
        if not myData.myGoldData[Index] or myData.myGoldData[Index] ~= 1 then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end

        local rewardCfg = config.Awards

        local rewards = rewardCfg[Index].awards

        myData.myGoldData[Index] = 2
        
        if IsBagGridEnough(sysarg, rewards) then
            GiveCommonAward(sysarg, rewards, LogIds.OperationLogId075, Lang.LogTips.Operation075)
        else
            local actorId = Actor.getActorId(sysarg)
            local title = Lang.ScriptTips.Operation055
            local content = Lang.ScriptTips.Operation056
            local sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            local vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
            Awards.GiveToMailById(actorId, rewards, title, content, LogIds.OperationLogId075, Lang.LogTips.Operation075, vocation, sex)
        end
    elseif opType == 2 then
        local canBuy = 0
        if cfg.end_time - time <= config.canSignBuyGoldTime then
            canBuy = 1
        end
        if canBuy == 0 then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation205, ttFlyTip)
            return
        end
        if not myData then
            myData = {}
        end
        if not myData.myGoldData then
            myData.myGoldData = {}
        end
        if myData.myGoldData[Index] and myData.myGoldData[Index] >= 1 then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation204, ttFlyTip)
            return
        end
        if not myData.myGoldBuyCount then
            myData.myGoldBuyCount = 0
        end
        if Index ~= 1 and not(myData.myGoldData[Index - 1] and myData.myGoldData[Index - 1] >= 1) then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation206, ttFlyTip)
            return
        end

        local needCostMoney = myData.myGoldBuyCount * config.everySignCostAdd + config.firstSignCostNum
        if Actor.getMoneyCount(sysarg, mtYuanbao) < needCostMoney then
            Actor.sendItemLack( sysarg, qatYuanbao, 0, needCostMoney )
            return
        end

        if not Actor.delMoney( sysarg,mtYuanbao,needCostMoney,LogIds.OperationLogId075,Lang.LogTips.Operation075) then
            return
        end

        local rewardCfg = config.Awards

        local rewards = rewardCfg[Index].awards

        myData.myGoldData[Index] = 2
        myData.myGoldBuyCount = myData.myGoldBuyCount + 1
        
        if IsBagGridEnough(sysarg, rewards) then
            GiveCommonAward(sysarg, rewards, LogIds.OperationLogId075, Lang.LogTips.Operation075)
        else
            local actorId = Actor.getActorId(sysarg)
            local title = Lang.ScriptTips.Operation055
            local content = Lang.ScriptTips.Operation056
            local sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
            local vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
            Awards.GiveToMailById(actorId, rewards, title, content, LogIds.OperationLogId075, Lang.LogTips.Operation075, vocation, sex)
        end
    else
        return
    end

    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_75, 1, newData)
        
    oper_act_75_packet_data(sysarg, cfg)
end


-- 跨天
function oper_act_75_new_day_arrive(act_id)  
    local players = LuaHelp.getAllActorList()
    if players then 
        for k, v in ipairs(players) do  
            oper_act_75_crossday(v)
        end
    end
end


--累计登录天数
function oper_act_75_crossday(sysarg)
    --print("oper_act_75_crossday pass here")
    local time = System.getSystemTime()
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_75_start then
        return
    end
    if not ssVar.oper_act_75_cmd then
        return
    end
    if not ssVar.oper_act_75_act then
        return
    end
    
    local cfg = get_oper_act_cfg(ssVar.oper_act_75_cmd, ssVar.oper_act_75_act)
    if not cfg then
        return
    end

    local config = cfg.config
    if not config then
        return
    end 

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_75, 1)

    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end
    if not myData.myGold then
        myData.myGold = 0
    end

    if myData.mySelfTime and System.isUnixTimeSameDay(myData.mySelfTime, time) then
        return
    end

    myData.myGold = myData.myGold + 1
    if not myData.myGoldData then
        myData.myGoldData = {}
    end
    for idx = 1, #config.Awards do
        if myData.myGoldData[idx] and myData.myGoldData[idx] >= 1 then
        else
            if config.Awards[idx].cond <= myData.myGold then
                myData.myGoldData[idx] = 1
            end
        end
    end


    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    myData.mySelfTime = time

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_75, 1, newData)
    oper_act_75_packet_data(sysarg, cfg)
end
